import {MatchDecorator, Decoration, ViewPlugin, WidgetType} from "@codemirror/view"
import {EditorView} from "codemirror"
import {deepClone, widgetIsSubFormType} from "@/utils/util";

class PlaceholderWidget extends WidgetType {
  field;
  text;
  type;

  constructor(text) {

    super();
    if (text) {
      //type 仅用于区分颜色
      this.text = text;
    }
  }

  eq(other) {
    return this.text === other.text;
  }

  // 此处是我们的渲染方法
  toDOM() {
    let elt = document.createElement('span');
    if (!this.text) return elt;
    elt.className = this.type === "func" ? "cm-function" : "cm-field";
    elt.textContent = this.text;
    return elt;
  }

  ignoreEvent() {
    return true;
  }
}


const placeholderMatcher = new MatchDecorator({
  regexp: /this.getFormValue/g,
  decoration: (match) =>
      Decoration.replace({
        widget: new PlaceholderWidget(match[0])
      })
});


export const placeholders = ViewPlugin.fromClass(class {
  placeholders

  constructor(view) {
    this.placeholders = placeholderMatcher.createDeco(view)
  }

  update(update) {
    this.placeholders = placeholderMatcher.updateDeco(update, this.placeholders)
  }
}, {
  decorations: instance => instance.placeholders,
  provide: plugin => EditorView.atomicRanges.of(view => {
    return view.plugin(plugin)?.placeholders || Decoration.none
  })
})


const noFieldData = ["tree", "button-group", "descriptions", "tree-transfer", "data-table",
  "sub-form", "grid-sub-form", "table-sub-form"]

export function buildTreeNodeOfWidget(widget, treeNode, isField = false) {

  const curNode = getWidgetOptions(widget);

  if (isField) {
    if (widget.formItemFlag) {
      treeNode.push(curNode)
    }
    //子表单不能作为表达式
    else if (!noFieldData.includes(widget.type) && (widget.category && (widget.widgetList && widget.widgetList.length > 0) || (widget.rows && widget.rows.length > 0) || (widget.cols && widget.cols.length > 0))) {
      treeNode.push(curNode)
    }
  } else {
    treeNode.push(curNode)
  }

  buildWidget(widget, curNode, isField);
}

export function getWidgetOptions(widget) {
  let curNode = {
    id: widget.options?.name || widget.id,
    title: (widget.type == "vf-dialog" || widget.type == "vf-drawer") ? widget.options?.title : "",
    category: widget.category,
    label: widget.options?.label || widget.label,
    type: widget.type,
    name: widget.options?.name,
    desc: `<${widget.options?.label || widget.label || widget.type}> ${widget.options?.name || widget.id}`,
    formItemFlag: widget.formItemFlag,
  }
  return deepClone(curNode);
}


export function buildWidget(widget, curNode, isField) {
  if (widget.category === undefined) {
    return
  }

  curNode.children = []
  if (widget.type === 'grid') {
    widget.cols.map(col => {
      const colNode = getWidgetOptions(col);
      colNode.label = col.options.name || widget.type,
          colNode.children = [];
      curNode.children.push(colNode)
      col.widgetList.map(wChild => {
        buildTreeNodeOfWidget(wChild, colNode.children, isField)
      })
    })
  } else if (widget.type === 'table') {
    //TODO: 需要考虑合并单元格！！
    widget.rows.map(row => {
      row.label = "table-row"

      const rowNode = getWidgetOptions(row);
      rowNode.label = "table-row";
      rowNode.type = "table-row";
      rowNode.children = [];
      rowNode.category = "category";
      curNode.children.push(rowNode)

      row.cols.map(cell => {
        if (!!cell.merged) {  //跳过合并单元格！！
          return
        }

        let rowChildren = rowNode.children
        const cellNode = getWidgetOptions(cell);
        cellNode.label = "table-cell";
        cellNode.children = [];
        cellNode.category = "category";
        rowChildren.push(cellNode)

        cell.widgetList.map(wChild => {
          buildTreeNodeOfWidget(wChild, cellNode.children, isField)
        })
      })
    })
  } else if (widget.type === 'tab') {
    widget.tabs.map(tab => {
      const tabNode = getWidgetOptions(tab);
      tabNode.children = [];
      curNode.children.push(tabNode)
      tab.widgetList.map(wChild => {
        buildTreeNodeOfWidget(wChild, tabNode.children, isField)
      })
    })
  } else if (widgetIsSubFormType(widget)) {
    widget.widgetList.map(wChild => {
      buildTreeNodeOfWidget(wChild, curNode.children, isField)
    })
  } else if (widget.category === 'container') {  //自定义容器
    if (widget.widgetList) {
      widget.widgetList.map(wChild => {
        buildTreeNodeOfWidget(wChild, curNode.children, isField)
      })
    }
  }
}